Centralized Image Storage with Custom Tag
Table of Contents
I implemented a feature to centrally organize my images under .assets/ folder that supports image preview and exporting to HTML with correct path.
1. Detailed Code
;;; image-storage.el --- sets up a centralized storage for images -*- lexical-binding:t -*-
;;; Commentary:
;;; Code:
(require 'ol)
(defconst my/org-image-asset-dir
(expand-file-name "~/org/.assets/"))
(org-link-set-parameters
"cimg"
:follow
(lambda (path _)
(find-file (expand-file-name path my/org-image-asset-dir)))
:image-data-fun
(lambda (_protocol path _description)
(with-temp-buffer
(insert-file-contents-literally
(expand-file-name path my/org-image-asset-dir))
(buffer-string)))
:complete
(lambda ()
(concat "cimg:"
(file-relative-name
(read-file-name "Image: " my/org-image-asset-dir)
my/org-image-asset-dir)))
:export
(lambda (path desc backend _info)
(cond
((eq backend 'html)
(format "<img src=\"/.assets/%s\" alt=\"%s\" />"
path
(or desc "")))
(t nil))))
(provide 'image-storage)
;;; image-storage.el ends here
ol imports th org-mode’s link library, which provides org-link-set-parameters function that allows custom link type definition. Here, we’ll use it to define our custom cimg: link type.
We first use defconst to define the root of our image storage.
Then, we start to define our link type. The link name is cimg, given by "cimg".
- Follow/open behaviour. Defined by
:follow, when we pressC-c C-o, Emacs opens~/org/.assets/...automatically for us. - Inline image display. Defined by
:image-data-fun, it lets Org fetch the raw image data for inline display. When Org tries to display images inline, it calls this function, reads the image file literally from the asset directory, and returns its contents as a string. - Link completion. Defined by
:complete, it provides completion support when inserting links. When Org asks for a link, it promptsImage:, after choosing a file, it converts the file path into a relative path and prefixes it withcimg:. - HTML export. Defined by
:export, when export Org to HTML, the lambda function converts[[cimg:...][desc]]into<img src="..." alt="..." />automatically.